/**
 * api/tickets
 */

const defaultToInteger = require('../../../utils/default-to-integer');
const sortQB = require('../../../utils/sort-qb')();
const md5 = require('../../../utils/md5');
const moment = require('moment');
const tickerHandler = require('../../../services/tickets-handler');


const weekdays = require('../../../data/weekdays');


module.exports = function(app) {
    const router = app.router;
    const Ticket = app.models.Ticket;
    const SpecialDate = app.models.SpecialDate;
    const TicketLog = app.models.TicketLog;
    const Log = app.models.Log;
    const Apply = app.models.Apply;

    const Type = app.models.Type;

    const rndNum = function(n) {
        let rnd = '';
        for(var i = 0; i < n; i++)
            rnd += Math.floor(Math.random() * 10);
        return rnd;
    };
    /**
     * @apiVersion 1.0.0
     * @apiGroup Ticket
     * @api {get} /tickets 获取角色列表
     * @apiParam {Number} status=ONLINE 上架状态 `0:OFFLINE, 1:ONLINE, 2:DEBUG`
     * @apiParam {Number} locate=home 角色位置 `home, post, ticket, home_ticket: 首页横幅`
     * @apiParam {Number} ticket=image 角色类型 `image, video`
     * @apiParam {Number} since 指定时间，单位秒
     * @apiParam {Number} page_size=20 分页大小
     * @apiParam {Number} page_num=1 页码
     * @apiParam {String} sort=priority-desc 排序，支持 `id-desc, id-asc, priority-desc`
     *
     * @apiParam {Number} status=1 `0:OFFLINE, 1:ONLINE, 2:DEBUG` 上架状态
     * @apiParam {Number} title 标题
     * @apiParam {String} locate 角色位置
     * @apiParam {String} scope 角色范围
     * @apiParam {String} scope_info 角色范围配置
     * @apiParam {String} ticket 角色类型 ``
     * @apiParam {String} asset_url 资源 URL
     * @apiParam {Number} width 宽
     * @apiParam {Number} height 高
     * @apiParam {Number} duration 角色时长，单位毫秒
     * @apiParam {String} url 跳转URL `如果为空则不跳转，其余按 H5内 `openPage.url` 和 全局规则`
     * @apiParam {Number} priority 排序优先级
     * @apiParam {Number} start_time 开始时间，单位秒
     * @apiParam {Number} end_time 结束时间，单位秒
     *
     * @apiSuccess {Number} status 上架状态
     * @apiSuccess {String} locate 角色位置 `home: ticket: recommed: 推荐位`
     * @apiSuccess {String} scope 角色范围
     * @apiSuccess {String} scope_info 角色范围配置
     * @apiSuccess {String} ticket 角色类型
     * @apiSuccess {String} asset_url 资源 URL
     * @apiSuccess {Number} width 宽
     * @apiSuccess {Number} height 高
     * @apiSuccess {Number} duration 角色时长，单位毫秒
     * @apiSuccess {String} url 跳转 URL `如果为空则不跳转，其余按 H5内 `openPage.url` 和 全局规则`
     ** @apiSuccess {Number} params 请求参数
     * @apiSuccess {Number} priority 排序优先级
     * @apiSuccess {Number} start_time 开始时间，单位秒
     * @apiSuccess {Number} end_time 结束时间，单位秒
     *
     * @apiSampleRequest
     */
    router.get('/tickets', function *() {
        const query = this.query;

        // @TODO: 支持 scpoe 查询
        const tickets = yield Ticket.query(qb => {
            if(query.deleted !== 'all') {
                if(query.deleted && +query.deleted !== 0) {
                    qb.where('tickets.deleted', query.deleted);
                }
                else {
                    qb.where('tickets.deleted', Ticket.NOT_DELETED);
                }
            }
            if((query.parent_id && query.parent_id !== 'all')) {
                qb.where('parent_id', query.parent_id);
            }
            if((query.type_id && query.type_id !== 'all')) {
                qb.where('type_id', query.type_id);
            }
            // if((query.parent_id && query.grand_id !== 'all')) {
            //     qb.where('grand_id', query.grand_id);
            // }
            if(query.status && query.status !== 'all') {
                let status = defaultToInteger(query.status, Ticket.ONLINE);
                qb.where('tickets.status', status);
            }
            if(query.ticket_no) {
                qb.where('ticket_no', 'like', '%' + query.ticket_no + '%');
            }
            if(query.apply_no) {
                qb.leftJoin('applys', function() {
                    this.on('tickets.apply_id', '=', 'applys.id');
                });
                qb.where('applys.apply_no', query.apply_no);
            }
            if(query.customer_id && query.customer_id !== 'all') {
                qb.where('customer_id', query.customer_id);
            }

            if(query.log_id && +query.log_id > 0) {
                qb.where('log_id', query.log_id);
            }

            if(query.apply_id && +query.apply_id > 0) {
                qb.where('apply_id', query.apply_id);
            }

            if(query.updated_at && query.updated_at > 0) {
                qb.where('updated_at', '>', new Date(+query.updated_at * 1000));
            }
            qb.orderBy('id', 'desc');
            // sort
            qb.orderBy('ticket_no', 'desc');
        })
        .fetchItems({
            page_size: query.page_size,
            page_num: query.page_num
        }, {
            withRelated: ['parent', 'types']
        });

        this.body = tickets;
    });

    router.get('/tickets/:id', function *() {
        if(+this.params.id > 0) {
            const ticket = yield Ticket.where({
                id: this.params.id
            })
            .fetch();

            this.body = ticket;
            return;
        }
        const ticket = yield Ticket.where({
            ticket_no: this.query.ticket_no,
        })
        .fetch({
            withRelated: ['parent', 'types', 'customer'],
            require: false
        });

        if(!ticket) {
            this.throw('票券不存在，请检查输入法，不支持五笔输入法下验票');
        }

        if(+this.params.id === 0 && this.query.type === 'front') {
            if(ticket.get('status') !== Ticket.UNUSED) {
                this.throw('票券非法或未激活');
            }

            const today = moment(new Date()).weekday();

            let canUse = (ticket.get('start_time') < new Date()) && (ticket.get('end_time') > new Date());
            const type = yield Type.where({
                id: ticket.get('type_id')
            })
            .fetch();
            if(type.get('weekdays') !== 0) {
                weekdays.map(item => {
                    if(item.value === today) {
                        canUse = item.id & ticket.get('weekdays');
                    }
                });
                if(canUse === 0) {
                    canUse = false;
                }
            }

            if(type.get('dates') !== 0) {
                const dates = yield SpecialDate.query(qb => {
                    qb.where('bit_id', '&', ticket.get('dates'));
                    qb.where('start_time', '>=', new Date());
                    qb.where('start_time', '<=', new Date());
                })
                .fetchAll();
                canUse = canUse || (dates.length > 0);
            }
            if(canUse) {
                ticket.set('b_percent', 0);
            }

            // const userId = this.headers['x-user'];

            // const log = Log.safeForge({
            //     creator: userId,
            //     ticket_id: ticket.get('id'),
            //     type: '前台验票'
            // });

            // yield log.save();

            // this.body = ticket;
        }

        if(+this.params.id === 0 && this.query.type === 'active') {
            if(ticket.get('status') !== Ticket.READY) {
                this.throw('该票券不是备售票券，无法激活');
            }
        }

        if(+this.params.id === 0 && this.query.type === 'confirm') {
            if(ticket.get('status') === Ticket.UNUSED) {
                this.throw('该票券未使用，无法核销');
            }
        }

        if(+this.params.id === 0 && this.query.type === 'destroy') {
            if(ticket.get('status') >= Ticket.UNUSED) {
                this.throw('该票券未使用或已使用，无法销毁');
            }
        }

        this.body = ticket;
    });

    /**
     * @apiVersion 1.0.0
     * @apiGroup Ticket
     * @api {post} /tickets 新建角色
     *
     * @apiParam {Number} status 上架状态
     * @apiParam {String} locate 角色位置
     * @apiParam {String} scope 角色范围
     * @apiParam {String} scope_info 角色范围配置
     * @apiParam {String} ticket 角色类型
     * @apiParam {String} asset_url 资源 URL
     * @apiParam {Number} width 宽
     * @apiParam {Number} height 高
     * @apiParam {Number} duration 角色时长，单位毫秒
     * @apiParam {String} url 跳转 URL，如果为空则不跳转，其余按 H5内 `openPage.url` 规则
     * @apiParam {Number} priority 排序优先级
     * @apiParam {Number} start_time 开始时间，单位秒
     * @apiParam {Number} end_time 结束时间，单位秒
     */
    router.post('/tickets', function *() {
        let body = this.request.body;

        if(body.num && body.num > 0) {

            // const start = body.start_no.replace(/[^0-9]/ig, '');
            // const end = body.end_no.replace(/[^0-9]/ig, '');
            // let prefix = body.end_no.replace(end, '');

            const tickets = [];

            const ticketLog = TicketLog.safeForge({
                start_no: body.start_no,
                end_no: body.end_no,
                num: body.num,
                remark: body.remark,
                type_id: body.type_id,
                parent_id: body.parent_id
            });

            yield ticketLog.save();

            const type = yield Type.where({
                id: body.type_id
            })
            .fetch();

            let prefix = 'DH' + type.get('code');

            for(let i = 0; i < body.num; i++) {
                // const zeros = Math.pow(10, end.length) + ''.replace('1', '');
                // const no = prefix + (zeros + (parseInt(start) + i)).slice(-end.length);
                tickets.push({
                    ticket_no: prefix + (body.start_no + i) + '.' + rndNum(3),
                    type_id: body.type_id,
                    parent_id: body.parent_id,
                    log_id: ticketLog.get('id'),
                    weekdays: type.get('weekdays'),
                    dates: type.get('dates')
                });
            }

            const ticketsModel = Ticket.Collection.forge(tickets);
            yield ticketsModel.invokeMap('save');

            const newTikcets = yield Ticket.where({
                log_id: ticketLog.get('id')
            })
            .fetchAll({
                withRelated: ['parent', 'grandpa']
            });

            this.body = {
                tickets: newTikcets
            };
            return;
        }
        this.body = [];
    });

    /**
     * @apiVersion 1.0.0
     * @apiGroup Ticket
     * @api {put} /tickets/:id 修改角色
     *
     * @apiParam {Number} status 上架状态
     * @apiParam {String} locate 角色位置
     * @apiParam {String} scope 角色范围
     * @apiParam {String} scope_info 角色范围配置
     * @apiParam {String} ticket 角色类型 ``
     * @apiParam {String} recommend_ticket `home_recommend: 首页顶部推荐, feature_recommend: 特性（标签）推荐, templet_recommend 模板库推荐`
     * @apiParam {String} asset_url 资源 URL
     * @apiParam {Number} width 宽
     * @apiParam {Number} height 高
     * @apiParam {Number} duration 角色时长，单位毫秒
     * @apiParam {String} url 跳转URL `如果为空则不跳转，其余按 H5内 `openPage.url` 和 全局规则`
     * @apiParam {Number} priority 排序优先级
     * @apiParam {Number} start_time 开始时间，单位秒
     * @apiParam {Number} end_time 结束时间，单位秒
     *
     * @apiSuccess {Number} status 上架状态
     * @apiSuccess {String} locate 角色位置 `home: ticket: recommed: 推荐位`
     * @apiSuccess {String} scope 角色范围
     * @apiSuccess {String} scope_info 角色范围配置
     * @apiSuccess {String} ticket 角色类型
     * @apiSuccess {String} asset_url 资源 URL
     * @apiSuccess {Number} width 宽
     * @apiSuccess {Number} height 高
     * @apiSuccess {Number} duration 角色时长，单位毫秒
     * @apiSuccess {String} url 跳转 URL `如果为空则不跳转，其余按 H5内 `openPage.url` 和 全局规则`
     * @apiSuccess {Number} priority 排序优先级
     * @apiSuccess {Number} start_time 开始时间，单位秒
     * @apiSuccess {Number} end_time 结束时间，单位秒
     */
    router.put('/tickets/:id', function *() {
        const body = this.request.body;
        const userId = this.headers['x-user'];

        if(this.params.id && +this.params.id > 0) {
            let ticket = yield Ticket.where({
                id: this.params.id
            })
            .fetch({
                withRelated: ['parent', 'grandpa', 'customer'],
            });

            if(body.ticket_no) {
                ticket = yield Ticket.where({
                    ticket_no: body.ticket_no
                })
                .fetch({
                    withRelated: ['parent', 'grandpa', 'customer'],
                });
                delete body.ticket_no;
            }

            if(!ticket) {
                this.throw('票券不存在');
            }

            delete body.parent;
            delete body.grandpa;
            delete body.childrens;
            delete body.types;
            delete body.subChildrens;

            if(body.status === Ticket.UNUSED && body.type !== 'cancel' && body.type !== 'special') {
                if(ticket.get('status') !== Ticket.READY) {
                    this.throw('该票券不是备售票券，无法激活, 或已经激活');
                }

                const log = Log.safeForge({
                    user_id: userId,
                    ticket_id: ticket.get('id'),
                    type: '激活'
                });

                yield log.save();
            }

            if(body.status === Ticket.COMPLETED && body.type !== 'special') {
                if(ticket.get('status') !== Ticket.USED) {
                    this.throw('该票券无法核销，确认票券已使用');
                }
                const log = Log.safeForge({
                    creator: userId,
                    ticket_id: ticket.get('id'),
                    type: '核销'
                });

                yield log.save();
            }
            if(body.deleted === 1) {
                const log = Log.safeForge({
                    creator: userId,
                    ticket_id: ticket.get('id'),
                    type: '销毁'
                });

                yield log.save();
            }

            if(body.type === 'special') {
                const log = Log.safeForge({
                    creator: userId,
                    ticket_id: ticket.get('id'),
                    type: '修改规则'
                });

                yield log.save();
            }

            delete body.type;
            if(body.end_time) {
                body.end_time = new Date(body.end_time * 1000);
            }

            if(body.start_time) {
                body.start_time = new Date(body.start_time * 1000);
            }

            ticket.safeSet(body);

            const log = Log.safeForge({
                creator: userId,
                ticket_id: ticket.get('id'),
                type: '核销'
            });

            yield log.save();

            yield ticket.save();
        }
        else {
            if(body.ticket_no) {
                console.log(body.ticket_no);
                const ticket = yield Ticket.where({
                    ticket_no: body.ticket_no
                })
                .fetch();

                if(body.apply_id && body.apply_id !== 0) {
                    if(ticket.get('apply_id')) {
                        this.throw(`${body.ticket_no}已分配`);
                    }
                    if(ticket.get('type_id') !== +body.type_id || ticket.get('parent_id') !== +body.parent_id) {
                        this.throw('票券类型和申请票券类型不一致');
                    }
                }
                else {
                    if(body.status === Ticket.UNUSED && body.type !== 'cancel' && body.type !== 'special') {
                        if(ticket.get('status') !== Ticket.READY) {
                            this.throw('该票券不是备售票券，无法激活, 或已经激活');
                        }

                        const log = Log.safeForge({
                            user_id: userId,
                            ticket_id: ticket.get('id'),
                            type: '激活'
                        });

                        yield log.save();
                    }

                    if(body.status === Ticket.COMPLETED && body.type !== 'special') {
                        if(ticket.get('status') !== Ticket.USED) {
                            this.throw('该票券无法核销，确认票券已使用');
                        }
                        const log = Log.safeForge({
                            creator: userId,
                            ticket_id: ticket.get('id'),
                            type: '核销'
                        });

                        yield log.save();
                    }
                    if(body.deleted === 1) {
                        const log = Log.safeForge({
                            creator: userId,
                            ticket_id: ticket.get('id'),
                            type: '销毁'
                        });

                        yield log.save();
                    }
                }

                delete body.id;
                delete body.start_ticket_no;
                delete body.end_ticket_no;

                if(body.end_time && +body.end_time > 0) {
                    if(body.end_time) {
                        body.end_time = new Date(body.end_time * 1000);
                    }
                    if(body.start_time) {
                        body.start_time = new Date(body.start_time * 1000);
                    }
                }
                delete body.days;
                ticket.safeSet(body);

                yield ticket.save();

                this.body = ticket;
                return;
            }

            if(body.start_ticket_no && body.start_ticket_no) {
                const ticket = yield Ticket.where({
                    ticket_no: body.start_ticket_no
                })
                .fetch();

                const endTicket = yield Ticket.where({
                    ticket_no: body.end_ticket_no
                })
                .fetch();
                body.start_time = new Date(body.start_time * 1000);

                if(body.end_time) {
                    body.end_time = new Date(body.end_time * 1000);
                }

                if(body.start_time) {
                    body.start_time = new Date(body.start_time * 1000);
                }
                if(ticket.get('id') > endTicket.get('id')) {
                    this.throw('起始编号小于结束编号');
                }

                const tickets = yield Ticket.query(qb => {
                    qb.where('type_id', body.type_id);
                    qb.where('parent_id', body.parent_id);
                    // qb.where('apply_id', body.apply_id);
                    qb.where('id', '>=', ticket.get('id'));
                    qb.where('id', '<=', endTicket.get('id'));
                })
                .fetchAll();

                const count = yield Ticket.where({
                    apply_id: body.apply_id,
                })
                .count();
                const apply = yield Apply.where({
                    id: body.apply_id
                })
                .fetch();
                let num = (apply.get('num') - count) || 0;
                num = num > tickets.length ? tickets.length : num;
                for(let i = 0; i < num; i++) {
                    tickets.models[i].set('status', body.status);
                    tickets.models[i].set('price', body.price);
                    tickets.models[i].set('apply_id', body.apply_id);
                    tickets.models[i].set('b_percent', body.b_percent);
                    tickets.models[i].set('end_time', body.end_time);
                    tickets.models[i].set('start_time', body.start_time);


                    yield tickets.models[i].save();
                }

                this.body = body;
                return;
            }
            if(body.operation) {
                const tickets = body.tickets;
                yield tickerHandler(tickets, userId, body.operation);
            }
        }

        this.body = body;
    });

    /**
     * @apiVersion 1.0.0
     * @apiGroup Ticket
     * @api {delete} /tickets/:id 删除角色
     */
    router.delete('/tickets/:id', function *() {
        let ticket = yield Ticket.where({
            id: this.params.id
        })
        .fetch({
            require: true
        });

        const userId = this.headers['x-user'];

        const log = Log.safeForge({
            creator: userId,
            ticket_id: ticket.get('id'),
            type: '注销'
        });

        yield log.save();

        ticket.set('deleted', Ticket.DELETED);

        yield ticket.save();

        this.body = this.params;
    });

    router.get('/tickets/export', function * () {

    });
};
